using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;


public class UdpFrameSync : MonoBehaviour
{   
    [Header("当前房间玩家人数")]
    public int PlayerNum;
    [Header("服务器的IP")]
    public string IP;
    [Header("服务器的监听端口")]
    public int sendPort;
    [Header("本机的监听端口")]
    public int receivePort;
    private UdpClient sender;
    private UdpClient receiver;
    // 接收的服务器数据--每一个玩家的数据
    [Header("x、y坐标输入")]
    public float[] positionX;
    public float[] positionY;
    [Header("目标旋转角")]
    public float[] rotationZ;
    [Header("攻击状态")]
    public bool[] attackState;
    [Header("背包同步")]
    public int[] bag;
    // 发送的数据
    [Header("当前玩家的ID")]
    public int PlayerId;
    [Header("当前玩家的位移")]
    public float PlayerPositionX;
    public float PlayerPositionY;
    [Header("当前玩家的旋转")]
    public float PlayerRotationZ;
    [Header("当前玩家的开火")]
    public bool PlayerAttackState;
    [Header("帧序号")]
    public int frameID;

    // Start is called before the first frame update
    void Start()
    {
        sender = new UdpClient();
        receiver = new UdpClient(receivePort);
        receiver.BeginReceive(ReceiveCallback, null);

        positionX = new float[PlayerNum];
        positionY = new float[PlayerNum];
        rotationZ = new float[PlayerNum];
        attackState = new bool[PlayerNum];

    }

    // Update is called once per frame
    void Update()
    {
        PcInput();
        UdpSend();

    }

    void PcInput()
    {
        // 获取水平方向和垂直方向的输入
        PlayerPositionX = Input.GetAxis("Horizontal");
        PlayerPositionY = Input.GetAxis("Vertical");

        // 获取鼠标位置
        Vector3 mousePosition = Input.mousePosition;
        mousePosition.x=mousePosition.x-Screen.width/2;
        mousePosition.y=Screen.height/2-mousePosition.y;
        // 计算旋转角度
        PlayerRotationZ = Mathf.Atan2(mousePosition.y, mousePosition.x) * Mathf.Rad2Deg;

    }

    void ReceiveCallback(IAsyncResult ar)
    {
        Debug.Log(111);
        IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
        byte[] receivedBytes = receiver.EndReceive(ar, ref remoteIpEndPoint);
        int receivedLength=17;
        for(int i=0;i<receivedBytes.Length/receivedLength;i++)
        {
            // Debug.Log(BitConverter.ToInt32(receivedBytes, i*receivedLength));
            frameID=BitConverter.ToInt32(receivedBytes, i*receivedLength)+1;
            positionX[i]=BitConverter.ToSingle(receivedBytes, i*receivedLength+4);
            
            positionY[i]=BitConverter.ToSingle(receivedBytes,i*receivedLength+8);
            rotationZ[i]=BitConverter.ToSingle(receivedBytes,i*receivedLength+12);
            attackState[i]=BitConverter.ToBoolean(receivedBytes,i*receivedLength+16);
        }

        // 继续监听
        receiver.BeginReceive(ReceiveCallback, null);
    }

    // 数据帧：玩家序号；帧序号；玩家位置；玩家旋转；开火指令；
    void UdpSend()
    {
        byte[] PlayerDataId = BitConverter.GetBytes(PlayerId);
        byte[] frameDataId = BitConverter.GetBytes(frameID);
        byte[] positionDataX = BitConverter.GetBytes(PlayerPositionX);
        byte[] positionDataY = BitConverter.GetBytes(PlayerPositionY);
        byte[] rotationDataZ = BitConverter.GetBytes(PlayerRotationZ);
        byte[] PlayerAttackDataState = new byte[1];
        PlayerAttackDataState[0] = (byte)(PlayerAttackState ? 1 : 0);
        int sendLength=frameDataId.Length+PlayerDataId.Length+ positionDataX.Length+ positionDataY.Length+ rotationDataZ.Length+PlayerAttackDataState.Length;
        byte[] sendData = new byte[sendLength];

        Buffer.BlockCopy(PlayerDataId, 0, sendData, 0, 4);
        Buffer.BlockCopy(frameDataId, 0, sendData, 4, 4);
        Buffer.BlockCopy(positionDataX, 0, sendData, 8, 4);
        Buffer.BlockCopy(positionDataY, 0, sendData, 12, 4);
        Buffer.BlockCopy(rotationDataZ, 0, sendData, 16, 4);
        Buffer.BlockCopy(PlayerAttackDataState, 0, sendData, 20 ,1);

        sender.Send(sendData, sendData.Length, IP, sendPort);
    }

    void OnDestroy()
    {
        if (sender != null)
        {
            sender.Close();
        }
    }
}
